package com.github.livebase.database;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import com.github.livebase.bean.EpgInformation;
import com.github.livebase.log.Logger;
import com.github.livebase.log.LoggerFactory;
import com.github.livebase.util.base.ObjectsUtil;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName EpgOperator
 * @description: epg 数据库操作类
 * @author: biao532
 * @create: 2023-12-27 14:47
 * @Version 1.0
 *
 **/

public class EpgOperator {
    // cols[day(int), channelId(String), start(int), end(int), title(String) ]
    private String tableName = "epgs_info";
    private SQLiteDatabase wdb;
    private SQLiteDatabase rdb;
    protected EpgOperator(SQLiteOpenHelper helper) {
        wdb = helper.getWritableDatabase();
        rdb = helper.getReadableDatabase();
    }
    private String select(String cols, String tableName, String where) {
        return String.format("select %s from %s where %s", cols, tableName, where);
    }

    public Integer getHash(int day) {
        String query = select("`end`", tableName, "`channelId`='CHANNEL_HASH' and `start`=?");
        Cursor cursor = rdb.rawQuery(query, new String[]{String.valueOf(day)});
        Integer integers = OperatorUtil.first(cursor, true, (c) -> c.getInt(0));
        cursor.close();
        return integers;
    }

    public void upsertHash(int day, int hash) {
        String sql = null;
        if (getHash(day) == null) {
            sql = "insert into %s (`start`, `end`, `channelId`) values (?, ?, 'CHANNEL_HASH')";
        }
        else {
            sql = "update %s set `start`=?, `end`=? where channelId='CHANNEL_HASH'";
        }
        sql = String.format(sql, tableName);
        wdb.execSQL(sql, new Object[]{day, hash});
    }

    public int insert(EpgInformation information) {
        ContentValues vals = new ContentValues();
        vals.put("channelId", information.getChannelId());
        vals.put("start", information.getStart());
        vals.put("end", information.getEnd());
        vals.put("title", information.getTitle());
        return (int) wdb.insert(tableName, "", vals);
    }

    public int delete(int day) {
        long start = tot(day);
        return delete(start);
    }
    public int delete(long dayStartTime) {
        long end = dayStartTime + 24*3600_000;
        return wdb.delete(tableName, "`start` >= ? and `end`<? ",
                new String[]{String.valueOf(dayStartTime), String.valueOf(end)});
    }

    public int deleteBefore(int day) {
        long start = tot(day);
        return wdb.delete(tableName, "`end`<? ",
                new String[]{String.valueOf(start)});
    }

    public List<EpgInformation> selectList(String channelId, int day) {
        long start = tot(day);
        long end = start + 24*3600_000;
        // end > ?start and start < ?end?
        String s = "select `start`, `end`, `title` from `%s` where channelId=? and `start`<? and `end`>? order by `start` asc, `end` asc";
        String[] vals = new String[]{channelId, String.valueOf(end), String.valueOf(start)};
        Cursor c = rdb.rawQuery(String.format(s, tableName), vals);
        List<EpgInformation> informations = OperatorUtil.cursorForeach(c, true, (cu)-> {
            return new EpgInformation(channelId, cu.getLong(0), cu.getLong(1), cu.getString(2));
        });
        c.close();
        return informations;
    }
    private long tot(int day) {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        try {
            return format.parse(String.valueOf(day)).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return System.currentTimeMillis();
    }
    public EpgInformation selectCurrent(String channelId, long time) {
        String s = "select `start`, `end`, `title` from `%s` where `channelId`=? and `start`<=? and `end` > ? limit 1";
        String[] vals = new String[]{channelId, String.valueOf(time), String.valueOf(time)};
        Cursor c = rdb.rawQuery(String.format(s, tableName), vals);
        EpgInformation informations = OperatorUtil.first(c, true, (cu)-> {
            return new EpgInformation(channelId, cu.getLong(0), cu.getLong(1), cu.getString(2));
        });
        c.close();
        return informations;
    }

    public EpgInformation selectNext(String channelId, long time) {
        String s = "select `start`, `end`, `title` from `%s` where `channelId`=? and `start`>? order by `start` asc, `end` asc limit 1";
        String[] vals = new String[]{channelId, String.valueOf(time)};
        Log.i("EpgOperator", String.format(s, tableName));
        Cursor c = rdb.rawQuery(String.format(s, tableName), vals);
        EpgInformation informations = OperatorUtil.first(c, true, (cu)-> {
            return new EpgInformation(channelId, cu.getLong(0), cu.getLong(1), cu.getString(2));
        });
        c.close();
        return informations;
    }
}
